package cn.js.sangu.unitStore.service.process;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.ref.SoftReference;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.EnumMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import javax.annotation.PreDestroy;
import org.apache.poi.EncryptedDocumentException;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.CellValue;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.FormulaEvaluator;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import cn.hutool.core.util.StrUtil;
import cn.js.sangu.unitStore.common.exception.ServiceException;
import cn.js.sangu.unitStore.dto.PartAttributeDTO;
import cn.js.sangu.unitStore.entity.ExcelData;
import cn.js.sangu.unitStore.entity.User;
import cn.js.sangu.unitStore.mapper.ExcelDataMapper;
import cn.js.sangu.unitStore.service.CodeLibService;
import cn.js.sangu.unitStore.utils.TokenUtils;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
// @Transactional(rollbackFor = Exception.class) //当前事务范围过大
public class ExcelProcessService {

    private final TokenUtils tokenUtils;

    // 新增常量（关键优化点）
    private static final int HEADER_ROW_COUNT = 3;

    @Autowired
    ExcelDataMapper excelDataMapper;

    @Autowired
    AutoCodeProcessService autoCodeProcessService;

    @Autowired
    MarkDuplicateCodes markDuplicateCodes;

    @Autowired
    CodeLibService codeLibService;

    @Autowired
    PartAttributesCheck partAttributesCheck; // 零件属性检查，包含编码前和编码后

    // 创建全局缓存，用于存储Workbook对象的软引用（优化点）
    private static final Map<String, SoftReference<Workbook>> workbookCache = new ConcurrentHashMap<>();

    // 在类中添加成员变量
    private FormulaEvaluator evaluator;

    // 在类中添加样式缓存
    private Map<IndexedColors, CellStyle> styleCache = new EnumMap<>(IndexedColors.class);

    ExcelProcessService(TokenUtils tokenUtils) {
        this.tokenUtils = tokenUtils;
    }

    // 建议添加缓存清理机制
    @PreDestroy
    public void clearStyleCache() {
        styleCache.clear();
    }

    // 新增样式获取方法
    private CellStyle getOrCreateStyle(Sheet sheet, IndexedColors color) {
        // return styleCache.computeIfAbsent(color, c -> createCellStyle(sheet, c));
        Workbook workbook = sheet.getWorkbook();
        return styleCache.computeIfAbsent(color, c -> {
            CellStyle newStyle = workbook.createCellStyle();
            newStyle.setFillForegroundColor(color.getIndex());
            newStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
            return newStyle;
        });
    }

    private CellStyle getOrCreateFontStyle(Sheet sheet, IndexedColors color) {
        Workbook workbook = sheet.getWorkbook();
        CellStyle cellStyle = workbook.createCellStyle();
        Font font = workbook.createFont();
        font.setColor(color.getIndex());
        cellStyle.setFont(font);
        return cellStyle;
    }

    // 抽离操作数据库的方法
    @Transactional
    public void databaseProcess(List<ExcelData> dataList, Workbook workbook, String filePath, Boolean autoCode,
            Long userId) {
        List<ExcelData> code11 = new ArrayList<>();
        List<ExcelData> code12 = new ArrayList<>();
        excelDataMapper.deleteExcelData();
        log.info("删除excel表数据成功");
        excelDataMapper.deleteExcel11Data();
        log.info("删除excel_11表数据成功");
        excelDataMapper.deleteExcel12Data();
        log.info("删除excel_12表数据成功");
        excelDataMapper.batchInsert(dataList);
        log.info("插入excel表数据成功");
        // 重置自增id
        excelDataMapper.resetAutoIncrement11();
        excelDataMapper.resetAutoIncrement12();
        // 筛选数据到临时表
        excelDataMapper.insertDataToExcel11();
        log.info("筛选并批量插入excel_11表数据成功");
        excelDataMapper.insertDataToExcel12();
        log.info("筛选并批量插入excel_12表数据成功");
        if (autoCode) {
            // 自动生成code
            if (autoCodeProcessService != null) {
                code11 = autoCodeProcessService.generateCodeList(excelDataMapper.findBy11(), userId.intValue());
                code12 = autoCodeProcessService.generateCodeList(excelDataMapper.findBy12(), userId.intValue());
                excelDataMapper.batchUpdateSyscodeBy11(code11);
                excelDataMapper.batchUpdateSyscodeBy12(code12);
            }
        }
    }

    // 通用方法，用于获取单元格的值并转换为指定类型
    // "D:\Install\Project\Trae\UtilStore\store\files\2025-05-06\Excel清单筛选模板-1746529896789.xlsx"
    public String dataProcess(String filePath, Boolean autoCode, Long userId) {
        // 增加空值检查，若 autoCode 为 null 则默认为 false
        autoCode = autoCode == null ? false : autoCode;
        List<ExcelData> dataList = new ArrayList<>();
        // try (Workbook workbook = WorkbookFactory.create(new File(filePath))) {
        try {
            // 修改后的缓存实现
            Workbook workbook = Optional.ofNullable(workbookCache.get(filePath))
                    .map(SoftReference::get)
                    .orElseGet(() -> {
                        try {
                            Workbook newWorkbook = WorkbookFactory.create(new File(filePath));
                            workbookCache.put(filePath, new SoftReference<>(newWorkbook));
                            return newWorkbook;
                        } catch (IOException e) {
                            throw new ServiceException("文件加载失败");
                        }
                    });
            // Workbook workbook = workbookCache.computeIfAbsent(filePath, k -> {
            // try {
            // return new SoftReference<>(WorkbookFactory.create(new File(filePath)));
            // } catch (IOException e) {
            // throw new ServiceException("文件加载失败");
            // }
            // }).get();

            // 禁用公式自动重算（性能优化关键点）
            workbook.setForceFormulaRecalculation(false);
            // 初始化公式求值器（新增）
            if (this.evaluator == null) {
                this.evaluator = workbook.getCreationHelper().createFormulaEvaluator();
            }
            Sheet sheet = workbook.getSheetAt(0);
            for (Row row : sheet) {
                // 使用常量替代魔法值（修改点）
                if (row.getRowNum() < HEADER_ROW_COUNT)
                    continue;
                ExcelData data = new ExcelData();
                setDataFields(data, row, workbook, autoCode);
                dataList.add(data);
            }

            // 新增：按tuhao升序排序（处理空值）
            // dataList.sort((d1, d2) -> {
            // String t1 = d1.getTuhao() != null ? d1.getTuhao() : "";
            // String t2 = d2.getTuhao() != null ? d2.getTuhao() : "";
            // return t1.compareTo(t2);
            // });

            // 新增：排序后统一生成编码（仅当autoCode为true时执行）
            // if (autoCode && autoCodeProcessService != null) {
            // for (ExcelData data : dataList) {
            // String code = autoCodeProcessService.generateCode(data);
            // log.info("====>自动生成code： [{}]", code);
            // data.setShuchu(code);
            // }
            // }
            // 抽离方法
            if (!dataList.isEmpty()) {
                databaseProcess(dataList, workbook, filePath, autoCode, userId);
            }
            // 标记重复的code，留有测试方法 抽出独立Service
            // markDuplicateCodes("11");
            // markDuplicateCodes("12");
            // 检查 markDuplicateCodes 是否为 null，避免空指针异常
            if (markDuplicateCodes != null) {
                try {
                    markDuplicateCodes.mainCommonByTable("11");
                    markDuplicateCodes.mainCommonByTable("12");
                } catch (Exception e) {
                    // 捕获异常并记录日志，方便后续排查问题
                    log.error("调用 MarkDuplicateCodes 的 mainCommonByTable 方法时出错", e);
                }
            }

            // 保存Excel文件
            try {
                if (workbook.getNumberOfSheets() > 0) {
                    // 保存Excel数据时，可以从数据库拿两个表数据，也可以在上面编码完成后不走数据库直接返回数据入参，这样可以减少数据库操作次数，提高效率。
                    return this.writeDataToExcelSheets(filePath, autoCode);
                } else {
                    throw new ServiceException("Excel文件损坏：" + filePath);
                }
            } catch (Exception e) {
                log.error("写入Excel文件失败，文件路径: {}", filePath, e);
                throw new ServiceException("写入Excel文件失败：" + e.getMessage());
            }
        } catch (EncryptedDocumentException e) {
            String errorMsg = e.getMessage() != null ? e.getMessage() : "加密文件无法处理";
            log.error("Excel文件读取失败(加密文件无法处理)，文件路径: {}", filePath, e);
            throw new ServiceException("Excel文件读取失败(加密文件无法处理)：" + errorMsg);
        } catch (Exception e) {
            log.error("数据处理异常，文件路径: {}", filePath, e);
            String errorMsg = e.getMessage() != null ? e.getMessage() : "发生未知的数据处理异常";
            throw new ServiceException("数据处理异常：" + errorMsg);
        }
        // 由于此代码块前已有 try-catch 块，若代码正常执行会在 try 块中返回，异常会在 catch 块抛出异常，此返回语句无法到达，故移除
        // 若需要保留该返回逻辑，需调整代码结构，当前先注释掉
        // return "处理失败";
    }

    private void setDataFields(ExcelData data, Row row, Workbook workbook, Boolean autoCode) {
        if (row == null || workbook == null) {
            log.error("row 或 workbook 为 null，跳过数据处理");
            return;
        }
        data.setXuhao(getCellValueString(row, 1, workbook));
        data.setTuhao(getCellValueString(row, 2, workbook));
        data.setName(getCellValueString(row, 3, workbook));
        data.setGuige(getCellValueString(row, 4, workbook));
        data.setCailiao(getCellValueString(row, 5, workbook));
        data.setCengjishu(getCellValueInteger(row, 6, workbook));
        data.setZongjishu(getCellValueInteger(row, 7, workbook));
        data.setDanzhong(getCellValueBigDecimal(row, 8, workbook));
        // data.setZongzhong(getCellValueGeneric(row, 9, BigDecimal.class, workbook));
        data.setLeibie(getCellValueString(row, 10, workbook));
        data.setBianma(getCellValueString(row, 11, workbook));
        data.setBeizhu(getCellValueString(row, 12, workbook));
        data.setXitong(getCellValueString(row, 13, workbook));
        // data.setShuchu(getCellValueString(row, 14, workbook));

        // 排序后再编码
        // if (autoCode && autoCodeProcessService != null) {
        // String code = autoCodeProcessService.generateCode(data);
        // log.info("====>自动生成code： [{}]",code);
        // data.setShuchu(code);
        // }
    }

    // 该方法用于获取指定行和列的单元格值，并将其转换为 Integer 类型返回。
    private Integer getCellValueInteger(Row row, int cellNum, Workbook workbook) {
        Cell cell = row.getCell(cellNum);
        // 检查单元格是否为空
        if (cell == null) {
            return 0;
        }
        if (cell.getCellType() == CellType.NUMERIC) {
            return (int) cell.getNumericCellValue(); // 转换为整数类型
        } else if (cell.getCellType() == CellType.STRING) {
            String strValue = cell.getStringCellValue().trim(); // 去除前后空格
            if (StrUtil.isNotBlank(strValue)) { // 检查字符串是否非空
                try {
                    return Integer.parseInt(strValue); // 转换为整数类型
                } catch (NumberFormatException e) {
                    log.error("无法解析字符串为整数：{}", strValue);
                }
            }
        } else if (cell.getCellType() == CellType.BOOLEAN) { // 处理布尔值类型的情况
            return cell.getBooleanCellValue() ? 1 : 0; // 转换为布尔值类型的字符串
        } else if (cell.getCellType() == CellType.FORMULA) { // 处理单元格类型为公式的情况
            // 创建一个公式求值器
            // FormulaEvaluator evaluator =
            // workbook.getCreationHelper().createFormulaEvaluator(); // 创建一个公式求值器
            if (evaluator == null) {
                this.evaluator = workbook.getCreationHelper().createFormulaEvaluator(); // 创建一个公式求值器
            }
            // 计算公式的值
            CellValue cellValue = evaluator.evaluate(cell); // 计算公式的值
            // 检查单元格值的类型
            if (cellValue.getCellType() == CellType.NUMERIC) { // 处理数值类型的情况
                return (int) cellValue.getNumberValue(); // 转换为整数类型的字符串
            } else if (cellValue.getCellType() == CellType.STRING) { // 处理字符串类型的情况
                String strValue = cellValue.getStringValue().trim(); // 去除前后空格
                if (StrUtil.isNotBlank(strValue)) { // 检查字符串是否非空
                    try {
                        return Integer.parseInt(strValue); // 转换为整数类型
                    } catch (NumberFormatException e) {
                        log.error("无法解析字符串为整数：{}", strValue); // 处理无法解析为整数的情况
                    }
                }
            }
        } else if (cell.getCellType() == CellType.BLANK) { // 处理单元格类型为空白的情况
            return 0; // 返回空字符串
        } else if (cell.getCellType() == CellType.ERROR) { // 处理单元格类型为错误的情况
            return 0; // 返回空字符串
        } else { // 处理其他类型的情况
            return 0; // 返回空字符串
        }
        return 0; // 返回空字符串
    }

    // 获取单元格的值并转换为指定类型的通用方法
    private String getCellValueString(Row row, int cellNum, Workbook workbook) {
        Cell cell = row.getCell(cellNum);
        // 检查单元格是否为空
        if (cell == null) {
            return "";
        }
        // 处理单元格类型为字符串的情况
        if (cell.getCellType() == CellType.STRING) {
            return cell.getStringCellValue().trim(); // 去除前后空格
        } else if (cell.getCellType() == CellType.NUMERIC) { // 处理单元格类型为数字的情况
            double numericCellValue = cell.getNumericCellValue(); // 获取单元格的数值
            if (numericCellValue > 100000000) { // 检查数值是否超过100000000
                return String.valueOf((long) numericCellValue); // 转换为长整数类型的字符串
            } else { // 处理数值小于100000000的情况
                // 修改 DecimalFormat 模式
                DecimalFormat decimalFormat = new DecimalFormat("#.###");
                return decimalFormat.format(numericCellValue); // 格式化数值为字符串
            }
        } else if (cell.getCellType() == CellType.BOOLEAN) { // 处理单元格类型为布尔值的情况
            return String.valueOf(cell.getBooleanCellValue()); // 转换为布尔值类型的字符串
        } else if (cell.getCellType() == CellType.FORMULA) { // 处理单元格类型为公式的情况
            // 创建一个公式求值器
            FormulaEvaluator evaluator = workbook.getCreationHelper().createFormulaEvaluator(); // 创建一个公式求值器
            // 计算公式的值
            CellValue cellValue = evaluator.evaluate(cell); // 计算公式的值
            // 检查单元格值的类型
            if (cellValue.getCellType() == CellType.NUMERIC) { // 处理数值类型的情况
                return String.valueOf(cellValue.getNumberValue()); // 转换为数值类型的字符串
            } else if (cellValue.getCellType() == CellType.STRING) { // 处理字符串类型的情况
                return cellValue.getStringValue().trim(); // 去除前后空格
            } else if (cellValue.getCellType() == CellType.BOOLEAN) { // 处理布尔值类型的情况
                return String.valueOf(cellValue.getBooleanValue()); // 转换为布尔值类型的字符串
            } else { // 处理其他类型的情况
                return ""; // 返回空字符串
            }
        } else if (cell.getCellType() == CellType.BLANK) { // 处理单元格类型为空白的情况
            return ""; // 返回空字符串
        } else if (cell.getCellType() == CellType.ERROR) { // 处理单元格类型为错误的情况
            return ""; // 返回空字符串
        } else { // 处理其他类型的情况
            return ""; // 返回空字符串
        }
    }

    // 获取单元格的值并转换为指定类型的通用方法
    private BigDecimal getCellValueBigDecimal(Row row, int cellNum, Workbook workbook) {

        Cell cell = row.getCell(cellNum);
        BigDecimal result = BigDecimal.ZERO;
        if (cell == null) {
            return result;
        }

        FormulaEvaluator evaluator = null;
        if (cell.getCellType() == CellType.FORMULA) {
            evaluator = workbook.getCreationHelper().createFormulaEvaluator();
        }

        CellType effectiveType;
        if (cell.getCellType() == CellType.FORMULA && evaluator != null) {
            effectiveType = evaluator.evaluate(cell).getCellType();
        } else {
            effectiveType = cell.getCellType();
        }

        switch (effectiveType) {
            case NUMERIC:
                double numericValue;
                if (cell.getCellType() == CellType.FORMULA && evaluator != null) {
                    numericValue = evaluator.evaluate(cell).getNumberValue();
                } else {
                    numericValue = cell.getNumericCellValue();
                }
                result = BigDecimal.valueOf(numericValue);
                break;
            case STRING:
                String strValue;
                if (cell.getCellType() == CellType.FORMULA && evaluator != null) {
                    strValue = evaluator.evaluate(cell).getStringValue();
                } else {
                    strValue = cell.getStringCellValue();
                }
                strValue = strValue.trim();
                if (StrUtil.isNotBlank(strValue)) {
                    try {
                        result = new BigDecimal(strValue);
                    } catch (NumberFormatException e) {
                        log.error("无法解析字符串为BigDecimal：{}", strValue);
                    }
                }
                break;
            case BOOLEAN:
                boolean boolValue;
                if (cell.getCellType() == CellType.FORMULA && evaluator != null) {
                    boolValue = evaluator.evaluate(cell).getBooleanValue();
                } else {
                    boolValue = cell.getBooleanCellValue();
                }
                result = boolValue ? BigDecimal.ONE : BigDecimal.ZERO;
                break;
            case BLANK:
            case ERROR:
                result = BigDecimal.ZERO;
                break;
            default:
                result = BigDecimal.ZERO;
        }

        return result.stripTrailingZeros();
    }

    // 写入数据到Excel文件
    // "D:\Project\Trae\store\store\files\2025-04-05\Excel清单筛选模板-1743843223062.xlsx"
    public String writeDataToExcelSheets(String excelPath, Boolean autoCode) {
        try {
            Workbook workbook = createWorkbook(excelPath);
            // 优化：缓存查询结果避免重复查询
            List<ExcelData> data11 = queryData11();
            List<ExcelData> data12 = queryData12();
            log.info("已查到新数据，准备写入Excel");
            createSheets(workbook, data11, data12, new String[] { "No", "序号", "图号", "名称", "规格", "材料", "总计数", "单重", "总重",
                    "类型", "编码", "备注", "系统识别", "查重输出", "自动编码", "系统备注" }, autoCode);
            log.info("已完成创建Sheet，准备生成Excel文件");
            String newFilePath = generateNewFilePath(excelPath);
            log.info("已生成Excel文件，准备写入数据");
            saveWorkbook(workbook, newFilePath);
            log.info("向Excel写入成功，文件路径: {}", newFilePath);
            return newFilePath;
        } catch (IOException e) {
            throw handleException("文件操作失败", excelPath, e);
        } catch (DataAccessException e) {
            throw handleException("数据库操作异常", excelPath, e);
        } catch (Exception e) {
            throw handleException("系统处理异常", excelPath, e);
        }
    }

    // 读取Excel文件并创建Workbook对象
    private Workbook createWorkbook(String excelPath) throws IOException, ServiceException {
        Workbook workbook = WorkbookFactory.create(new File(excelPath));
        if (workbook.getNumberOfSheets() == 0) {
            throw new ServiceException("Excel文件损坏：" + excelPath);
        }
        return workbook;
    }

    // 从数据库查询数据
    private List<ExcelData> queryData11() {
        return excelDataMapper.findBy11();
    }

    private List<ExcelData> queryData12() {
        return excelDataMapper.findBy12();
    }

    // 创建Sheets并写入数据
    private void createSheets(Workbook workbook, List<ExcelData> dataList11, List<ExcelData> dataList12,
            String[] headers, Boolean autoCode) {
        createSheetWithIncrementalName(workbook, "图纸清单", dataList11, headers, autoCode);
        createSheetWithIncrementalName(workbook, "标准件清单", dataList12, headers, autoCode);
        log.info("创建Excel-Sheets成功");
    }

    // 创建Sheet并写入数据，确保名称不重复
    private Sheet createSheetWithIncrementalName(Workbook workbook, String sheetName, List<ExcelData> dataList,
            String[] headers, Boolean autoCode) {
        int index = 1;
        while (workbook.getSheetIndex(sheetName) != -1) {
            sheetName += " (" + index + ")";
            index++;
        }
        Sheet sheet = workbook.createSheet(sheetName);
        // 正式写入数据到Sheet
        writeDataToSheet(sheet, dataList, headers, autoCode);
        return sheet;
    }

    // 生成新的Excel文件路径
    private String generateNewFilePath(String excelPath) {
        String fileName = new File(excelPath).getName();
        int dotIndex = fileName.lastIndexOf('.');
        String baseName = dotIndex == -1 ? fileName : fileName.substring(0, dotIndex);
        String extension = dotIndex == -1 ? "" : fileName.substring(dotIndex);
        String newFileName = baseName + "-处理完成" + extension;
        return new File(excelPath).getParent() + File.separator + newFileName;
    }

    // 保存Workbook到文件
    private void saveWorkbook(Workbook workbook, String newFilePath) throws IOException, ServiceException {
        try (FileOutputStream fileOut = new FileOutputStream(newFilePath)) {

            // 在写入前清除样式缓存
            styleCache.clear();
            if (workbook instanceof SXSSFWorkbook) {
                SXSSFWorkbook sxssfWorkbook = (SXSSFWorkbook) workbook;
                sxssfWorkbook.write(fileOut);
                ((SXSSFWorkbook) workbook).dispose(); // 仅针对SXSSFWorkbook调用（内存优化）
            } else {
                workbook.write(fileOut);
            }
            // fileOut.flush(); //不必要的刷新操作（try-with-resources会自动处理）
        } catch (IOException e) {
            log.error("写入Excel文件失败: ", e);
            throw new ServiceException("写入Excel文件失败：" + e.getMessage());
        } catch (Exception e) {
            log.error("写入Excel文件时发生未知异常: ", e);
            throw new ServiceException("写入Excel文件失败：" + e.getMessage());
        }
    }

    private ServiceException handleException(String errorType, String filePath, Exception e) {
        String errorMsg = StrUtil.isNotBlank(e.getMessage()) ? e.getMessage() : "未知错误";
        log.error("{} [文件路径：{}] - {}", errorType, filePath, errorMsg, e);
        return new ServiceException(String.format("%s：%s", errorType, errorMsg));
    }

    // 正式写入数据到Sheet
    private void writeDataToSheet(Sheet sheet, List<ExcelData> dataList, String[] headers, Boolean autoCode) {
        int rowNum = 2; // 修改起始行号为2（对应Excel第3行）
        Row headerRow = sheet.createRow(rowNum++);
        for (int i = 0; i < headers.length; i++) {
            headerRow.createCell(i).setCellValue(headers[i]);
        }
        // CellStyle pinkCellStyle = getOrCreateStyle(sheet, IndexedColors.ROSE);
        // CellStyle tanCellStyle = createCellStyle(sheet, IndexedColors.TAN);
        CellStyle orangeCellStyle = getOrCreateStyle(sheet, IndexedColors.YELLOW);
        CellStyle lightGreenCellStyle = getOrCreateStyle(sheet, IndexedColors.LIGHT_GREEN);
        CellStyle redFontStyle = getOrCreateFontStyle(sheet, IndexedColors.RED);

        for (ExcelData data : dataList) {
            Row row = sheet.createRow(rowNum++);
            row.createCell(0).setCellFormula("ROW()-3");
            // setCellValue(row, 0, data.getId() != null ? data.getId() : 0);
            setCellValue(row, 1, data.getXuhao() != null ? data.getXuhao() : "");
            setCellValue(row, 2, data.getTuhao() != null ? data.getTuhao() : "");
            setCellValue(row, 3, data.getName() != null ? data.getName() : "");
            setCellValue(row, 4, data.getGuige() != null ? data.getGuige() : "");
            setCellValue(row, 5, data.getCailiao() != null ? data.getCailiao() : "");
            setCellValue(row, 6, data.getZongjishu() != null ? data.getZongjishu() : 0);
            setCellValue(row, 7, data.getDanzhong() != null ? data.getDanzhong().toString() : "0");
            // setCellValue(row, 8, data.getZongzhong() != null ?
            // data.getZongzhong().toString() : "0");
            row.createCell(8).setCellFormula("G" + rowNum + "*H" + rowNum);
            // 添加公式求值器计算结果
            FormulaEvaluator evaluator = sheet.getWorkbook().getCreationHelper().createFormulaEvaluator();
            evaluator.evaluateAll();
            setCellValue(row, 9, data.getLeibie() != null ? data.getLeibie() : "");
            setCellValue(row, 10, data.getBianma() != null ? data.getBianma() : "");
            setCellValue(row, 11, data.getBeizhu() != null ? data.getBeizhu() : "");
            setCellValue(row, 12, data.getXitong() != null ? data.getXitong() : "");
            setCellValue(row, 13, data.getShuchu() != null ? data.getShuchu() : "");
            setCellValue(row, 14, data.getSyscode() != null ? data.getSyscode() : "");
            // setCellValue(row, 15, data.getRemark() != null ? data.getRemark() : "");
            CellStyle style = null;
            if (sheet.getSheetName().contains("图纸清单") && "标准件".equals(data.getLeibie())) {
                style = lightGreenCellStyle; // 绿色
            } else if ("组件".equals(data.getLeibie())) {
                style = orangeCellStyle; // 橙色
            }
            // 只有自动编码时才会检验和提示
            if (autoCode) {
                if (data.getBianma().equals("27817115213000")) {
                    System.out.println(data.toString());
                }

                String value = "";
                boolean hint = false;

                if (StrUtil.isNotBlank(data.getRemark())) {
                    // 备注非空
                    if (StrUtil.isNotBlank(data.getBianma()) && StrUtil.isNotBlank(data.getSyscode())
                            && !data.getBianma().equals(data.getSyscode())) {
                        if (hint) {
                            value = "自动编码不一致," + data.getRemark();
                        } else {
                            // 无需提示信息，直接修改
                            if (data.getSyscode().length() >= 14) {
                                // 将syscode的第7-14位替换为10位时间戳的后8位以保证唯一性
                                String syscode = data.getSyscode();
                                // 获取当前时间戳(13位)
                                long timestamp = System.currentTimeMillis();
                                // 取时间戳后8位
                                String timestampSuffix = String.valueOf(timestamp).substring(5);
                                // 替换第7-14位(索引6-13)
                                syscode = syscode.substring(0, 6) + timestampSuffix + syscode.substring(14);
                                data.setSyscode(syscode);
                                setCellValue(row, 14, syscode);
                                value = "已时间戳去重";
                            }
                        }
                    } else {
                        value = data.getRemark();
                    }
                } else {
                    // 备注为空
                    if (StrUtil.isNotBlank(data.getBianma()) && StrUtil.isNotBlank(data.getSyscode())
                            && !data.getBianma().equals(data.getSyscode())) {
                        value = "自动编码不一致";
                    }
                }

                setCellValue(row, 15, value);
                data.setRemark(value);
            }

            // 查重输出单元格有异常信息
            // if (StrUtil.isNotBlank(data.getShuchu()) ||
            // StrUtil.isNotBlank(data.getRemark())) {
            // // autoCode=false时原有逻辑
            // // style = pinkCellStyle;
            // // log.info( "系统有输出异常信息：{}",data.getShuchu());
            // row.getCell(14).setCellStyle(redFontStyle);
            // }
            if (StrUtil.isNotBlank(data.getRemark())) {
                row.getCell(14).setCellStyle(redFontStyle);
            }

            if (style != null) {
                // 应用样式到整行
                for (int i = 0; i < row.getLastCellNum(); i++) {
                    // row.getCell(i).setCellStyle(style); //非替换样式
                    Cell cell = row.getCell(i);
                    if (cell != null) {
                        Workbook workbook = cell.getSheet().getWorkbook();
                        // 克隆原有的单元格样式
                        CellStyle newStyle = workbook.createCellStyle();
                        if (cell.getCellStyle() != null) {
                            newStyle.cloneStyleFrom(cell.getCellStyle());
                        }
                        // 合并新的样式
                        newStyle.setFillForegroundColor(style.getFillForegroundColor());
                        newStyle.setFillPattern(style.getFillPattern());
                        // 设置新的字体样式
                        Font newFont = workbook.createFont();
                        if (newStyle.getFontIndex() != 0) {
                            Font oldFont = workbook.getFontAt(newStyle.getFontIndex());
                            // newFont.cloneStyleFrom(oldFont);
                            newFont.setFontName(oldFont.getFontName());
                            newFont.setFontHeightInPoints(oldFont.getFontHeightInPoints());
                            newFont.setBold(oldFont.getBold());
                            newFont.setItalic(oldFont.getItalic());
                            newFont.setStrikeout(oldFont.getStrikeout());
                            newFont.setUnderline(oldFont.getUnderline());
                            newFont.setTypeOffset(oldFont.getTypeOffset());
                            newFont.setColor(oldFont.getColor());
                        }
                        // Font styleFont = workbook.getFontAt(style.getFontIndex());
                        // newFont.setColor(styleFont.getColor());
                        // newStyle.setFont(newFont);

                        // 应用新样式到单元格
                        newStyle.setFont(newFont);
                        // 应用新样式到单元格
                        cell.setCellStyle(newStyle);
                    }
                }
            }
        }

        // 自动调整列宽
        for (int i = 0; i < headers.length; i++) {
            sheet.autoSizeColumn(i);
        }
    }

    private void setCellValue(Row row, int cellNum, Object value) {
        row.createCell(cellNum).setCellValue(value.toString());
    }

    public String test() {
        // this.markDuplicateCodes("11");
        // this.markDuplicateCodes("12");

        // return "ok";

        // return
        // dataProcess("D:\\Install\\Project\\Trae\\UtilStore\\store\\files\\2025-05-06\\Excel清单筛选模板-1746529896789.xlsx",
        // true);

        ExcelData excelData = new ExcelData();
        excelData.setTuhao("25-20-6分");
        excelData.setName("水路软管对接三通");
        excelData.setGuige("25-20-6分");
        excelData.setCailiao("PA Type 6");
        excelData.setLeibie("标准件");

        User currentUser = TokenUtils.getCurrentUser();
        String code = autoCodeProcessService.generateCode(excelData, currentUser.getId(), "测试");
        log.info("====>自动生成code： [{}]", code);
        return code;
    }

    /**
     * 自动生成编码
     * 
     * @param data      Excel数据对象
     * @param creatorId 创建者ID（可选），当在非Web请求线程中调用时可以传入
     * @return 生成的编码
     */
    public String autocode(ExcelData data, Integer creatorId, String remark) {
        // 执行任务前更新Map数据
        autoCodeProcessService.updateMapsBeforeTask();
        // 直接调用generateCode方法，该方法内部已包含完整的重复检查逻辑
        // 避免在此处进行重复的属性检查，提高性能和代码维护性
        String code = autoCodeProcessService.generateCode(data, creatorId, remark);
        log.info("====>自动生成code： [{}]", code);
        return code;
    }

    // 反向解析属性
    public PartAttributeDTO parseAttributes(String code) {
        return autoCodeProcessService.parseAttributes(code);
    }

    public void clearCount() {
        // 初始化lastVariableAMap
        autoCodeProcessService.clearSequenceMap();
    }
}